#include <my_head.h>

int main(int argc, const char *argv[]){
    if(3 != argc){
        printf("Usage : %s <IP> <PORT>\n", argv[0]);
        exit(EXIT_FAILURE);
    }
    // 创建套接字
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if(-1 == sockfd)
        ERR_LOG("socket error");
    
    // 填充服务器网络信息结构体
    struct sockaddr_in serveraddr;
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(atoi(argv[2]));
    serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
    socklen_t serveraddr_len = sizeof(serveraddr);

    // 将套接字和服务器网络信息结构体绑定
    if(-1 == bind(sockfd, (struct sockaddr *)&serveraddr, serveraddr_len))
        ERR_LOG("bind error");

    // 将套接字设置成被动监听状态
    if(-1 == listen(sockfd, 5))
        ERR_LOG("listen error");
    
    // 定义结构体 保存客户端的信息
    struct sockaddr_in clientaddr;
    socklen_t clientaddr_len = sizeof(clientaddr);

    int nbytes = 0;
    char buff[128] = {0};
    // 阻塞等待客户端连接
    int acceptfd = 0;
    while(1){
        printf("正在等待客户端连接...\n");
        if(-1 == (acceptfd = accept(sockfd, (struct sockaddr *)&clientaddr, &clientaddr_len))){
            ERR_LOG("accept error");
        }
        printf("客户端[%s:%d]连接到服务器..\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
        while(1){
            // 收发数据
            // 接收客户端发来的数据
            if(-1 == (nbytes = recv(acceptfd, buff, sizeof(buff), 0))){
                ERR_LOG("recv error");
            }else if(0 == nbytes){
                printf("客户端[%s:%d]断开连接..\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
                break;
            }
            if(!strcmp(buff, "quit")){
                printf("客户端[%s:%d]退出了..\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
                break;
            }
            // 处理数据（打印到终端）
            printf("客户端[%s:%d]发来数据[%s]\n", \
                    inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port), buff);
            // 组装应答消息
            strcat(buff, "--beijing");
            // 给客户端发送应答消息
            if(-1 == send(acceptfd, buff, sizeof(buff), 0)){
                ERR_LOG("send error");
            }
        }
        // 关闭套接字
        close(acceptfd);
    }
    // 关闭套接字
    close(sockfd);

    return 0;
}